package com.young.simpleweb.config;

import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.young.simpleweb.interceptors.CommonInterceptor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;

/**
 * @author ：young
 * @date ：Created in 2019/7/19
 * @description：MVC配置
 */
@Component
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    private static Logger logger = LogManager.getLogger(WebMvcConfig.class);

    /**
     * 拦截器添加
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //此处可以添加多个拦截器
        //多个拦截器按照顺序执行
        registry.addInterceptor(new CommonInterceptor());
        //本地开发环境搞东西可以将认证类型的参数焊死
//        registry.addInterceptor(new DevSignValidateInterceptor());
    }

    /**
     * Configure content negotiation options.
     *
     * @param configurer
     */
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8);
    }

    /**
     * JSON MessageConverter
     * 序列化反序列化转换器
     *
     * @param converters
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
//        保留空的字段
//        config.setSerializerFeatures(SerializerFeature.WriteMapNullValue);
//        String null -> ""
//        config.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty);
//        Number null -> 0
//        config.setSerializerFeatures(SerializerFeature.WriteNullNumberAsZero);
//         按需配置，更多参考FastJson文档哈
        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(Charset.forName("UTF-8"));
        converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON_UTF8));
        /**
         * 这个操作很重要，
         * 因为：{@link converters}中会有
         * {@link StringHttpMessageConverter}
         * {@link ByteArrayHttpMessageConverter}
         * {@link ResourceHttpMessageConverter}
         * 等这些转换类，有一定顺序，如果Controller中的方法返回结果是：String等类型
         * 会出错{@link StringHttpMessageConverter},因为返回结果已经做了统一格式处理
         * 使用{@link FastJsonHttpMessageConverter},什么类型就都可以转换
         */
        converters.add(0, new MappingJackson2HttpMessageConverter());
        converters.add(1, converter);
    }

    /**
     * 全局异常处理机制
     *
     * @param exceptionResolvers
     */
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
        exceptionResolvers.add(new CommonHandlerExceptionResolver());
    }

    /**
     * 解决跨域问题
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //registry.addMapping("/**");
    }
}
